import paramiko
from scp import SCPClient
import os
import time
import re
import glob
from pathlib import Path
import datetime


def get_latest_ansible_scripts():
    """
    获取agent-mcp/Ansible目录下最新日期文件夹中的所有脚本
    :return: 脚本文件路径列表，按文件名排序
    """
    try:
        # 尝试多种可能的路径
        possible_paths = [
            Path("agent-mcp/Ansible"),  # 相对路径
            Path.cwd() / "agent-mcp/Ansible",  # 当前工作目录 + 相对路径
            Path(__file__).parent.parent / "agent-mcp/Ansible",  # 脚本所在目录的上级目录
        ]

        ansible_path = None
        for path in possible_paths:
            if path.exists():
                ansible_path = path
                print(f"找到Ansible目录: {ansible_path}")
                break

        if ansible_path is None:
            print(f"Ansible目录不存在，尝试的路径: {[str(p) for p in possible_paths]}")
            return []

        # 查找所有日期格式的子目录 (YYYYMMDDHHMMSS)
        date_pattern = re.compile(r'^\d{14}$')
        date_dirs = []
        
        for item in ansible_path.iterdir():
            if item.is_dir() and date_pattern.match(item.name):
                date_dirs.append(item)
        
        if not date_dirs:
            print("未找到日期格式的目录")
            return []
        
        # 按目录名排序，获取最新的目录
        latest_dir = sorted(date_dirs, key=lambda x: x.name, reverse=True)[0]
        print(f"最新日期目录: {latest_dir}")
        
        # 获取该目录下的所有.sh脚本
        script_files = list(latest_dir.glob("*.sh"))
        script_files.sort(key=lambda x: x.name)  # 按文件名排序
        
        print(f"找到 {len(script_files)} 个脚本文件:")
        for script in script_files:
            print(f"  - {script.name}")
        
        return script_files
        
    except Exception as e:
        print(f"获取脚本文件时出错: {e}")
        return []

def run_ansible_tuning(test_id, script_path):
    # SSH连接配置
    host = "192.168.100.135"
    port = 22
    username = "root"
    private_key = paramiko.RSAKey.from_private_key_file("C:/Users/32793/.ssh/id_rsa")

    # 设置本地结果目录 (绝对路径+当前时间点文件夹)
    now_str = datetime.datetime.now().strftime("%Y%m%d%H%M")
    abs_base_dir = r"E:\code\python_code\PythonProject18_8_9_14_06\PythonProject18\ansible_python\python\ansible_kylin"
    local_result_dir = os.path.join(abs_base_dir, now_str)
    os.makedirs(local_result_dir, exist_ok=True)

    try:
        # 建立SSH连接
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, port, username, pkey=private_key)

        # 1. 上传调优脚本到银河麒麟
        remote_script_dir = "/opt/kylin_optimizer/generated_scripts"
        script_name = os.path.basename(script_path)
        remote_script_path = f"{remote_script_dir}/{script_name}"

        # 确保远程目录存在
        ssh.exec_command(f"mkdir -p {remote_script_dir}; chmod 755 {remote_script_dir}")

        with SCPClient(ssh.get_transport()) as scp:
            scp.put(script_path, remote_script_path)

        # 2. 执行Ansible Playbook
        playbook_cmd = (
            f"ansible-playbook /opt/kylin_optimizer/tune.Kylin.yml "
            f"-e 'test_id={test_id} generated_script_path={remote_script_path}'"
        )
        stdin, stdout, stderr = ssh.exec_command(playbook_cmd)

        # 等待命令执行完成
        exit_status = stdout.channel.recv_exit_status()
        output = stdout.read().decode()
        error = stderr.read().decode()

        if exit_status != 0:
            raise Exception(f"Ansible执行失败: {error}\n{output}")

        # 3. 下载三个结果文件
        result_files = [
            f"/opt/kylin_optimizer/results/{ test_id }/perf_data/{test_id}_pre_tune.txt",
            f"/opt/kylin_optimizer/results/{ test_id }/perf_data/{test_id}_post_tune.txt",
            f"/opt/kylin_optimizer/results/{ test_id }/perf_data/{test_id}_output.txt"
        ]

        local_files = []
        for remote_file in result_files:
            # 构建本地文件名
            file_name = os.path.basename(remote_file)
            local_path = os.path.join(local_result_dir, file_name)

            # 下载文件
            with SCPClient(ssh.get_transport()) as scp:
                try:
                    scp.get(remote_file, local_path)
                    local_files.append(local_path)
                except Exception as e:
                    print(f"警告: 文件 {remote_file} 下载失败: {str(e)}")

        return local_files

    finally:
        ssh.close()


def run_all_latest_scripts(test_id):
    """
    执行最新目录下的所有脚本
    :param test_id: 测试ID
    :return: 所有脚本的执行结果
    """
    # 获取最新目录下的所有脚本
    script_files = get_latest_ansible_scripts()
    
    if not script_files:
        print("未找到可执行的脚本文件")
        return []
    
    all_results = []
    
    # 为每个脚本生成唯一的test_id
    for i, script_path in enumerate(script_files, 1):
        script_name = script_path.name
        unique_test_id = f"{test_id}_script_{i}"
        
        print(f"\n=== 执行脚本 {i}/{len(script_files)}: {script_name} ===")
        print(f"使用测试ID: {unique_test_id}")
        
        try:
            # 执行单个脚本
            result_files = run_ansible_tuning(unique_test_id, str(script_path))
            
            result_info = {
                "script_name": script_name,
                "script_path": str(script_path),
                "test_id": unique_test_id,
                "result_files": result_files,
                "success": len(result_files) > 0
            }
            
            all_results.append(result_info)
            
            print(f"脚本 {script_name} 执行完成")
            print(f"结果文件数量: {len(result_files)}")
            
        except Exception as e:
            print(f"脚本 {script_name} 执行失败: {e}")
            
            result_info = {
                "script_name": script_name,
                "script_path": str(script_path),
                "test_id": unique_test_id,
                "result_files": [],
                "success": False,
                "error": str(e)
            }
            
            all_results.append(result_info)
    
    return all_results


# 使用示例
# if __name__ == "__main__":
#     # 执行最新目录下的所有脚本
#     test_id = "test2025"
#     all_results = run_all_latest_scripts(test_id)
#
#     print(f"\n=== 执行总结 ===")
#     print(f"总脚本数量: {len(all_results)}")
#
#     success_count = sum(1 for result in all_results if result.get('success', False))
#     print(f"成功执行: {success_count} 个")
#     print(f"失败执行: {len(all_results) - success_count} 个")
#
#     print(f"\n详细结果:")
#     for i, result in enumerate(all_results, 1):
#         status = "✅ 成功" if result.get('success', False) else "❌ 失败"
#         print(f"{i}. {result['script_name']}: {status}")
#
#         if result.get('success', False):
#             print(f"   结果文件: {len(result['result_files'])} 个")
#         else:
#             print(f"   错误信息: {result.get('error', '未知错误')}")



def Kylin_1():
    # 执行最新目录下的所有脚本
    test_id = "test2024"
    all_results = run_all_latest_scripts(test_id)

    print(f"\n=== 执行总结 ===")
    print(f"总脚本数量: {len(all_results)}")

    success_count = sum(1 for result in all_results if result.get('success', False))
    print(f"成功执行: {success_count} 个")
    print(f"失败执行: {len(all_results) - success_count} 个")

    print(f"\n详细结果:")
    for i, result in enumerate(all_results, 1):
        status = "✅ 成功" if result.get('success', False) else "❌ 失败"
        print(f"{i}. {result['script_name']}: {status}")

        if result.get('success', False):
            print(f"   结果文件: {len(result['result_files'])} 个")
        else:
            print(f"   错误信息: {result.get('error', '未知错误')}")